package com.qf.openapi2204.zuul.filter;

import cn.hutool.crypto.digest.DigestUtil;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;

@Component
public class SignFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 15;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        boolean result = currentContext.sendZuulResponse();

        return result;
    }

    @Override
    public Object run() throws ZuulException {

        //1. 计算签名
        // 签名算法文档：https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3

        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();

        // 1.1 获取所有请求参数的参数名字
        Set<String> paramNameSet = request.getParameterMap().keySet();

        // 1.2 安装ascii的顺序对请求参数进行升序排序
        ArrayList<String> paramNameList = new ArrayList<>(paramNameSet);

        paramNameList.sort(String::compareTo);

        // 1.3 拼串 StringA
        StringBuilder stringBuilder = new StringBuilder();

        for (String paramName : paramNameList) {
            if (paramName.equals("sign")){
                continue;
            }

            String paramValue = request.getParameter(paramName);
            if (paramValue!=null){
                stringBuilder.append(paramName);
                stringBuilder.append("=");
                stringBuilder.append(paramValue);
                stringBuilder.append("&");
            }
        }

        String stringA = stringBuilder.toString();

        // 1.4 拼 密钥
        String appkey = request.getParameter("app_key");

        String appSecret = getAppSecret(appkey);

        String stringSignTemp = stringA + "key=" + appSecret;

        // 1.5 md5
        String sign = DigestUtil.md5Hex(stringSignTemp).toUpperCase();
        System.out.println("系统计算的sign:"+sign);

        //2. 比对签名是否正确
        String paramSign = request.getParameter("sign");
        System.out.println("请求传递的sign:"+paramSign);

        // 签名出错
        if (!paramSign.equals(sign)){
            // 请求到此结束，不要在往后面的微服务发送了
            currentContext.setSendZuulResponse(false);

            HttpServletResponse response = currentContext.getResponse();
            response.setContentType("text/html;charset=utf-8");
            try {
                response.getWriter().println("签名错误!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        return null;
    }

    private String getAppSecret(String appkey) {
        return "ff2ff43192a84bb49988720c307182c8";
    }
}
